package com.googlecode.groovy_toy_orm

import com.googlecode.groovy_toy_orm.framework.BaseFunctionalTest
import com.googlecode.groovy_toy_orm.internal.CodeBased
import org.testng.annotations.Test

import static com.googlecode.groovy_toy_orm.MapperUtil.transform
import static com.googlecode.groovy_toy_orm.MapperUtil.transformBack



class MapperTest extends BaseFunctionalTest {


    enum Codez implements CodeBased {
        OK(0), SOMETHING_TERRIBLE(20);

        final int code;

        Codez(code) {
            this.code = code
        }

        static Codez fromCode(int code) {
            try {
                values().grep { it.code == code }.last()
            } catch (NoSuchElementException e) {
                throw new UnsupportedOperationException("Unsupported code:${code} (Exception was ${e})")
            }
        }
    }


    static enum YesNo {
        Y, N
    }

    static class UsesYesNo {
        def boolOption
        def enabled
    }


    @Test
    void stringEnumTest() {
        asTest {
            Mapper ohYesMapper = new Mapper(new MapperFields().with {
                field('boolOption')
                field('enabled', 'enabled', transform.stringEnum(YesNo), transformBack.stringEnum(YesNo))
                delegate as MapperFields
            })
            Map res = [:]

            asStep("trasnformMap") {
                res = ohYesMapper.transformMap([boolOption: "ZeOption", enabled: "Y"])

                assert res.enabled == YesNo.Y
                assert res.enabled instanceof YesNo
                assert res == [boolOption: "ZeOption", enabled: YesNo.Y]
            }
            asStep("mapBack") {
                assert ohYesMapper.mapBack(res) == [boolOption: "ZeOption", enabled: "Y"]
            }

            asStep("fieldValues") {
                assert ohYesMapper.getMappedFieldValues(new UsesYesNo(boolOption:false, enabled: YesNo.Y))==[boolOption:false, enabled: YesNo.Y]
            }
        }

    }






    @Test
    void positiveDefaultTransformationsTest() {
        asTest() {
            asStep() {
                Mapper messageMapper = new Mapper(new MapperFields().with {
                    field("code", "retCode")
                    field(new Field(name: 'description', from: ["msg", "detail"],
                            transform:
                                    { Field f, Map map -> "${map['msg']}|${map['detail']}" },
                            transformBack:
                                    { Field f, def value ->
                                        List elements = (value as String).split('\\|');
                                        return [msg: elements[0], detail: elements[1]] as Map
                                    }
                    ))
                    delegate as MapperFields
                })

                def source = [retCode: 20, msg: "A Message", detail: 'Blah-blah']
                Map res = messageMapper.transformMap(source)
                assert messageMapper.mapBack(res) == source

            }

            asStep() {
                Mapper messageMapper = new Mapper(new MapperFields().with {
                    field("RetCode", ["RetCode"], transform.codeBasedEnum(Codez.class), transformBack.codeBasedEnum(Codez.class))
                    field("RetText")
                    delegate as MapperFields
                })

                def source = [RetCode: 20, RetText: "Ouch!"]

                Map rez = messageMapper.transformMap(source)
                println rez
                assert messageMapper.mapBack(rez) == source
                println messageMapper.mapBack(rez)
            }
        }
    }

}
